/**
 * Copyright (c) 2010 icer He <icerhe@gmail.com>
 */
package com.icerhe.trigger;

import com.icerhe.trigger.task.AlarmTask;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.media.MediaPlayer.OnErrorListener;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Vibrator;
import android.telephony.CellLocation;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

/**
 * 播放铃声和振动的service
 * @author icer
 */
public class RingtonService extends Service {
	
	public static final String RINGTON_ENABLED = "RINGTON_ENABLED";
	public static final String VIBRATOR_ENABLED = "VIBRATOR_ENABLED";
	public static final String RINGTON_URI = "RINGTON_URI";
    
	//通话状态使用的铃声音量
    private static final float IN_CALL_VOLUME = 0.125f;	
	//铃声振动最大持续秒数,
	private static final int TIMEOUT_SECOND = 60*10; //10 minutes
	//振动模式
	private static final long[] vibratePattern = new long[] { 500, 500 };
	
	private Vibrator vibrator;
	private MediaPlayer mediaPlayer;
	private TelephonyManager telephonyManager;
	
	//当前播放状态 正在播放:true
	private boolean isPlaying = false;
	//service启动时的电话CallState
	private int initialCallState;
	
	private PhoneStateListener phoneStateListener = new PhoneStateListener() {
		@Override
		public void onCallStateChanged(int state, String incomingNumber) {
			super.onCallStateChanged(state, incomingNumber);
			//如果在通话中触发alarm,那么phoneStateListener会因为通话状态而停掉服务,
			//所以这里再检查下初始状态initialCallState,以保证phoneState有变化且不是
			//CALL_STATE_IDLE的时候才执行
			if (state!=TelephonyManager.CALL_STATE_IDLE && state!=initialCallState) {
				//  
				stopSelf();
			}
		}
	};
	
	private static final int KILLME = 1024;
	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			if (msg.what==KILLME) {
				Log.d(Consts.TAG, "RingtonService kill itself.");
				stopSelf();
			}
		}
	};
	
	@Override
	public void onCreate() {
		vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
		telephonyManager = 
			(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
		//监听电话状态,如果有电话打进来则停止铃声和振动
		telephonyManager.listen(
				phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
		TaskWakeLock.acquireWakeLock(this);
	}
	
	



	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		//service.onStartCommand()返回值为START_STICKY的service
		//所属的process被kill后,系统会尝试重建此service,且传入的intent为null
		//所以当intent为null时,应该停止服务并阻止系统继续重建service
		if (intent == null) {
            stopSelf();
            return START_NOT_STICKY;
        }
		
		boolean ringtonEnabled = intent.getBooleanExtra(RINGTON_ENABLED, true);
		boolean vibratorEnabled = intent.getBooleanExtra(VIBRATOR_ENABLED, true);

		String ringtonUri = intent.getStringExtra(RINGTON_URI);

		play(ringtonUri, ringtonEnabled, vibratorEnabled);
		
		initialCallState = telephonyManager.getCallState();
		
		return START_STICKY;
	}

	@Override
	public void onDestroy() {
		stop();
		//停止监听电话来电状态
		telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
		TaskWakeLock.releaseLock();
	}
	
	/**
	 * 响铃&振动
	 * @param rington 铃声的uri地址
	 * @param ringtonEnabled 是否响铃
	 * @param VibratorEnabled 是否振动
	 */
	private void play(String rington, boolean ringtonEnabled, boolean vibratorEnabled) {
		//停止可能正在播放的铃声和振动
		stop();
		Log.d(Consts.TAG, "RingtonService play: "+ rington);
		
		if (ringtonEnabled) {
			
			Uri ringtonUri;
			
			if (rington==null) {
				ringtonUri = RingtoneManager.getDefaultUri(
	                    RingtoneManager.TYPE_ALARM);
			} else {
				ringtonUri = Uri.parse(rington);
			}
			
			mediaPlayer = new MediaPlayer();
			mediaPlayer.setOnErrorListener(new OnErrorListener() {
	            public boolean onError(MediaPlayer mp, int what, int extra) {
	                Log.e(Consts.TAG, "Error occurred while playing rington.");
	                mp.stop();
	                mp.release();
	                mediaPlayer = null;
	                return true;
	            }
	        });
	        
	        try {
	        	if (telephonyManager.getCallState()
	        			!=TelephonyManager.CALL_STATE_IDLE) {//通话中,降低音量
	        		Log.d(Consts.TAG, "use the in call alarm ");
	        		mediaPlayer.setVolume(IN_CALL_VOLUME, IN_CALL_VOLUME);
	        		mediaPlayer.setDataSource(this, ringtonUri);	
	        	} 
	        	mediaPlayer.setDataSource(this, ringtonUri);
	        	startPlay(mediaPlayer);
	        } catch (Exception e) {
	        	//当播放指定铃声失败(比如mp3铃音在sd卡上,而sd卡挂载到pc上了)
	        	//时使用fallbackring
	        	Log.d(Consts.TAG, "use the fallback ring");
	        	try {
	        		mediaPlayer.reset();
	        		AssetFileDescriptor afd = 
	        			getResources().openRawResourceFd(R.raw.fallbackring);
	        		if (afd!=null) {
	        			mediaPlayer.setDataSource(
	        					afd.getFileDescriptor(), 
	        					afd.getStartOffset(), 
	        					afd.getLength());
	        			afd.close();
	        		}
	        		startPlay(mediaPlayer);
	        	} catch(Exception e2) {
	        		Log.e(Consts.TAG, "failed to play fallback ring");
	        	}
	        }
		}
		
		if (vibratorEnabled) {
			vibrator.vibrate(vibratePattern, 0);
		} else {
			vibrator.cancel();
		}
		
		//在TIMEOUT_SECOND秒后停止铃声和振动,免得手机闹腾一整天
		handler.sendMessageDelayed(
				handler.obtainMessage(KILLME), TIMEOUT_SECOND*1000);
		isPlaying = true;
		
	}
	
	private void startPlay(MediaPlayer player) 
		throws java.io.IOException, IllegalArgumentException,
			   IllegalStateException {
		final AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
        // do not play alarms if stream volume is 0
        // (typically because ringer mode is silent).
		//当STREAM_ALARM音量为0时不播放铃声(通常是由于响铃模式被设置为"静音")
        if (audioManager.getStreamVolume(AudioManager.STREAM_ALARM) != 0) {
            player.setAudioStreamType(AudioManager.STREAM_ALARM);
            player.setLooping(true);
            player.prepare();
            player.start();
        }
	}

	private void stop() {
		Log.d(Consts.TAG, "RingtonService stop.");
		if (isPlaying) {
			isPlaying = false;
			
			//停止铃声
			if (mediaPlayer!=null) {
				mediaPlayer.stop();
				mediaPlayer.release();
				mediaPlayer =null;
			}
			//停止振动
			vibrator.cancel();
		}
		
		handler.removeMessages(KILLME);
	}

	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}

}
